package com.EventObject;

import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.TimeUnit;

//通常情况，我们会有一个事件发布者，它本身作为事件源，在合适的时机，将相应的事件发布给对应的事件监听器：
//在合适的时机发布事件。此例中的 methodMonitor() 方法是事件发布的源头，其在方法执行之前和结束之后两个时间点发布 MethodMonitorEvent 事件，每个时间点发布的事件都会传给相应的监听器进行处理。
//在具体实现时需要注意的是，事件发布是顺序执行，为了不影响处理性能，事件监听器的处理逻辑应尽量简单。
//事件监听器的管理。publisher 类中提供了事件监听器的注册与移除方法，这样客户端可以根据实际情况决定是否需要注册新的监听器或者移除某个监听器。
//如果这里没有提供 remove 方法，那么注册的监听器示例将一直被 MethodMonitorEventPublisher 引用，即使已经废弃不用了，也依然在发布者的监听器列表中，这会导致隐性的内存泄漏。
public class MethodMonitorEventPublisher {

	private List<MethodMonitorEventListener> listeners = new ArrayList<>();

	public void methodMonitor() throws InterruptedException{
		MethodMonitorEvent eventObject = new MethodMonitorEvent(this);
		publishEvent("begin", eventObject);
		TimeUnit.SECONDS.sleep(2);
		publishEvent("end", eventObject);
	}

	private void publishEvent(String status, MethodMonitorEvent event) {
		List<MethodMonitorEventListener> copyListeners = new ArrayList<>(listeners);
		for (MethodMonitorEventListener listener : copyListeners) {
			if("begin".equals(status)){
				listener.onMethodBegin(event);
			}else{
				listener.onMethodEnd(event);
			}
		}
	}

	public static void main(String[] args) throws InterruptedException {
		MethodMonitorEventPublisher t = new MethodMonitorEventPublisher();
		t.listeners.add(new AbstractMethodMonitorEventListener());
		t.methodMonitor();
	}

}
